﻿using System;
using System.Collections.Generic;
using Gameplay.PVE.Utils;
using UnityEngine;
using Yoozoo.Gta.Common;
using Yoozoo.Libs;
using Yoozoo.Managers;

namespace Gameplay.PVE.Survivor
{
    public class TruckUnit : NpcUnit
    {
        private MapRoute route;
        private int currentIndex;
        private Vector3 targetPosition;
        private Vector3 nextTargetPosition;
        private bool routeValid;

        private TruckWheel wheel;
        private BattleGameObject effModel;

        private bool inRange = false;

        private float maxSpeed = 1f;

        public void InitTruck(int routeId)
        {
            route = StageManager.Instance.GetRoute(routeId);
            currentIndex = 0;
            routeValid = true;
            FindTargetPosition();
        }

        public override void InitComponents()
        {
            this.rendererReadyCallback = OnTruckReady;
            renderComponent = AddComponent<RenderComponent>();
            hudComponent = AddComponent<HudComponent>();
            AddComponent<CollisionComponent>();
            //hudComponent.SetShowHud(false);
        }

        public override void InitHero()
        {
            base.InitHero();
            maxSpeed = 1;
            if (npcConfig != null)
            {
                if (npcConfig.move_speed > 0)
                {
                    maxSpeed = npcConfig.move_speed;
                }
            }
        }

        private void OnTruckReady(GameObject gameObject)
        {
            wheel = gameObject.GetComponentInChildren<TruckWheel>();
            wheel.Initialize();
            var path = StageManager.Instance.GetTruckPath(route.id);
            wheel.StartMoveByPath(path);
            effModel = BattlePoolManager.Instance.Get(701);
            var scale = culFollowRange();
            effModel.Scale = new Vector3(scale, 1, scale);
            effModel.Parent = gameObject.transform;
            // effModel.LocalPosition = Vector3.zero;
            effModel.LocalPosition = new Vector3(0, 0.3f, 0);
            effModel.EulerAngle = Vector3.zero;
            gameObject.transform.position = route.points[0];
            gameObject.transform.forward = route.points[1] - route.points[0];
            Forward = wheel.forward;
            checkInTruck();
            //wheel.SimulateRoute(route.points);
            //wheel.ShowLine();
        }

        private void FindTargetPosition()
        {
            nextTargetPosition = BattleConstValue.DEFAULT_POINT;
            var nextPointIndex = currentIndex + 1;
            if (nextPointIndex >= route.points.Count)
            {
                routeValid = false;
            }
            else
            {
                targetPosition = route.points[nextPointIndex];
                if (nextPointIndex + 1 < route.points.Count)
                {
                    nextTargetPosition = route.points[nextPointIndex + 1];
                }
            }
        }

        protected override bool CheckCanAddElement(ElementConfig elementConfig)
        {
            return elementConfig.main_type == (int)EBattleElementMainType.Damage &&
                   elementConfig.sub_type == (int)EBattleElementSubType.NormalDamage;
        }

        public float culFollowRange()
        {
            return 8.0f;
            // var directionToTruck = StageManager.Instance.TeamGroup.Position - this.Position;
            // if (Vector3.Angle(directionToTruck, this.forward) > 90)
            // {
            //     //BattleDebug.LogError("领先了");
            //     var screenRatio = 1;
            //     var camera = CameraManager.Instance.MainCamera;
            //     var screenPos = camera.WorldToScreenPoint(position);
            //     var screenWidth = Screen.width;
            //     var screenHeight = Screen.height;
            //     var horizontalRatio = Mathf.Min(screenPos.x,screenWidth - screenPos.x) / screenWidth;
            //     var verticalRatio = Mathf.Min(screenPos.y,screenHeight - screenPos.y) / screenHeight;
            //     var ratioLimit = 0.2f;
            //     var minRatio = Mathf.Min(horizontalRatio, verticalRatio);
            //     minRatio = Mathf.Clamp(minRatio,0.05f,1);
            //     if (minRatio < ratioLimit)
            //     {
            //         targetSpeed *= minRatio;
            //     }
            // }
        }

        protected override void OnUpdate()
        {
            if (wheel == null)
            {
                return;
            }

            if (routeValid)
            {
                wheel.MoveByPath();
                Position = wheel.position;
                Forward = wheel.forward;
                //检测障碍物
                CheckObstacle();
            }
        }

        private Bullet debugBullet
        {
            get
            {
                if (m_debugBullet == null)
                {
                    m_debugBullet = ClassManager.Get<Bullet>();
                }

                return m_debugBullet;
            }
        }

        private Bullet m_debugBullet;

        private Bullet debugBullet2
        {
            get
            {
                if (m_debugBullet2 == null)
                {
                    m_debugBullet2 = ClassManager.Get<Bullet>();
                }

                return m_debugBullet2;
            }
        }

        private Bullet m_debugBullet2;
        private float stopTimer = 0;
        private float stopLastTime;

        private void CheckObstacle()
        {
            //第一步，检测车头前的长方形
            var shape = (int)EBulletShapeType.Rect;
            var param1 = 2f;
            var param2 = 1.5f;
            var pos = position + forward.normalized * 3.5f;
            var targetList = CollisionManager.Instance.GetCollisionGroup(pos, forward, shape, param1, param2);
            if (SurvivorManager.showCollision)
            {
                CollisionManager.Instance.ShowBulletCollision(debugBullet, targetList, pos, forward, shape,
                    param1, param2);
            }

            var targetSpeed = maxSpeed;
            if (targetList.Count > 0)
            {
                targetSpeed = 0;
            }
            else
            {
                pos = position + forward.normalized * 4.5f;
                param2 = 5;
                targetList = CollisionManager.Instance.GetCollisionGroup(pos, forward, shape, param1, param2);
                if (SurvivorManager.showCollision)
                {
                    CollisionManager.Instance.ShowBulletCollision(debugBullet2, targetList, pos, forward, shape,
                        param1, param2);
                }

                for (int i = 0; i < targetList.Count; i++)
                {
                    var unit = UnitManager.Instance.GetUnitById(targetList[i]);
                    if (unit is EnvironmentUnit evn && !evn.isDead)
                    {
                        //BattleDebug.LogError(evn.unitId);
                        targetSpeed = 0;
                        break;
                    }
                }
            }

            //如果货车领先我，则需要判断是否在屏幕内
            var directionToTruck = StageManager.Instance.TeamGroup.Position - this.Position;
            if (Vector3.Angle(directionToTruck, this.forward) > 90)
            {
                //BattleDebug.LogError("领先了");
                var screenRatio = 1;
                var camera = CameraManager.Instance.MainCamera;
                var screenPos = camera.WorldToScreenPoint(position);
                var screenWidth = Screen.width;
                var screenHeight = Screen.height;
                var horizontalRatio = Mathf.Min(screenPos.x, screenWidth - screenPos.x) / screenWidth;
                var verticalRatio = Mathf.Min(screenPos.y, screenHeight - screenPos.y) / screenHeight;
                var ratioLimit = 0.2f;
                var minRatio = Mathf.Min(horizontalRatio, verticalRatio);
                minRatio = Mathf.Clamp(minRatio, 0.05f, 1);
                if (minRatio < ratioLimit)
                {
                    targetSpeed *= minRatio;
                }
            }

            //targetSpeed *= maxSpeed;
            wheel.SetTargetTimeScale(targetSpeed);
            if (targetSpeed == 0)
            {
                if (stopTimer == 0)
                {
                    stopTimer = TimeManager.time;
                }
                else
                {
                    if (TimeManager.time - stopTimer > 0.5f)
                    {
                        stopLastTime += TimeManager.time - stopTimer;
                        stopTimer = TimeManager.time;
                        stopEvent();
                    }
                }
            }
            else
            {
                if (stopTimer != 0)
                {
                    stopTimer = 0;
                    stopLastTime = 0;
                }
            }

            checkInTruck();
        }

        void stopEvent()
        {
            HeroEventBubbleManager.Instance.StopTime(unitId, stopLastTime);
        }

        void checkInTruck()
        {
            var dis = Vector3.Distance(StageManager.Instance.TeamGroup.Position, this.Position);
            if (dis > culFollowRange())
            {
                if (inRange)
                {
                    inRange = false;
                    var inRangeShow = 1;
                    SurvivorManager.Instance.ShowTruckTips(true);
                }
            }
            else
            {
                if (inRange == false)
                {
                    inRange = true;
                    SurvivorManager.Instance.ShowTruckTips(false);
                }
            }
        }
    }
}